/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package chconfig

import (
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/common/options"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/ichain"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/util/concurrent/lazycache"
	"github.com/pkg/errors"
)

type Provider func(chainID string) (ichain.ChainConfigService, error)

type CacheKey interface {
	lazycache.Key
	Context() ichain.ClientContext
	ChainID() string
	Provider() Provider
}

type cacheKey struct {
	key     string
	chainID string
	context ichain.ClientContext
	pvdr    Provider
}

func NewCacheKey(ctx ichain.ClientContext, pvdr Provider, chainID string) (CacheKey, error) {
	return &cacheKey{
		key:     chainID,
		chainID: chainID,
		context: ctx,
		pvdr:    pvdr,
	}, nil
}

func NewRefCache(opts ...options.Opt) *lazycache.Cache {
	initializer := func(key lazycache.Key) (interface{}, error) {
		ck, ok := key.(CacheKey)
		if !ok {
			return nil, errors.New("unexpected cache key")
		}
		return NewRef(ck.Context(), ck.Provider(), ck.ChainID(), opts...), nil
	}

	return lazycache.New("Chain_Cfg_Cache", initializer)
}

func (k *cacheKey) String() string {
	return k.key
}

func (k *cacheKey) Context() ichain.ClientContext {
	return k.context
}

func (k *cacheKey) ChainID() string {
	return k.chainID
}

func (k *cacheKey) Provider() Provider {
	return k.pvdr
}
